import { DataSource, DataSourceOptions, Entity, InsertResult, Repository } from "typeorm";
import { AccountEntity } from "../../../account_server/entity/AccountEntity";
import { UserEntity } from "../../../account_server/entity/UserEntity";
import { DbConfig } from "../../config/DbConfig";
import { Logger } from "./Logger";

export class DBSourceManager {

    public static instance: DBSourceManager = new DBSourceManager();

    private dataSourceMap: Map<string, DataSource> = new Map<string, DataSource>()


    public init() {

    }

    public async createClient(dbName: string, dbType: number) {
        let realDbName: string = this.getCodeDbName(dbName, dbType)
        let dbConfig: DbConfig = DbConfig.getDbConfig(dbType)
        let entityList: Array<any> = DbConfig.getDbEntity(dbName)
        let dataSouce: DataSource = new DataSource({
            type: "mysql",
            host: dbConfig.host,
            port: dbConfig.port,
            username: dbConfig.user,
            password: dbConfig.pass,
            database: dbName,
            synchronize: true,
            logging: true,
            subscribers: [],
            migrations: [],
            entities: entityList,
        })
        if (!dataSouce.isInitialized) {
            let initReulst = await dataSouce.initialize()
        }
        this.dataSourceMap.set(realDbName, dataSouce)
        return dataSouce;
    }


    private getCodeDbName(dbName: string, dbType: number) {
        let realDbName: string = dbName + "_db" + dbType
        return realDbName;
    }

    public async getDb(dbName: string, dbType: number = DbConfig.now_db_type) {
        let db: DataSource = null
        let realDbName: string = this.getCodeDbName(dbName, dbType)
        if (this.dataSourceMap.has(realDbName)) {
            db = this.dataSourceMap.get(realDbName)
        } else {
            db = await this.createClient(dbName, dbType)
        }
        return db;
    }



    public async insert(repository: Repository<any>, entity: any) {
        try {
            let result: InsertResult = await repository.insert(entity);
            return result
        } catch (error) {
            Logger.error("Repository.insert=", error)
            return null
        }
    }


    public async query(repository: Repository<any>, sql: string, sqlParams?: any[]) {
        try {
            let results = await repository.query(sql, sqlParams)
            return results
        } catch (error) {
            Logger.error("Repository.query=", error)
        }
        return []
    }


}